package com.hjdb88;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.util.*;

/**
 * 签名工具
 */
public class SignUtil {
    private SignUtil() {
    }

    /**
     * 生成待签名原文
     *
     * @param object 参数
     * @return
     */
    public static String createStrToSign(Object object) {
        JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(object));
        return sortJsonObject(jsonObject);
    }

    private static String sortJsonObject(JSONObject jsonObject) {
        if (jsonObject.isEmpty()) {
            return null;
        }

        StringBuilder sb = new StringBuilder();

        List<String> keys = new ArrayList(jsonObject.keySet());
        Collections.sort(keys);
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            String key = it.next();
            Object value = jsonObject.get(key);

            if ("sign".equals(key)) {
                continue;
            }

            if (value instanceof JSONObject) {
                value = sortJsonObject((JSONObject) value);
            } else if (value instanceof JSONArray) {
                value = sortJsonArray((JSONArray) value);
            } else {
                if (value == null) {
                    value = "";
                } else if (!(value instanceof String || value instanceof Integer)) {
                    throw new IllegalArgumentException("unsupported param type");
                }
            }
            if (null != value) {
                sb.append("&").append(key).append("=").append(value);
            }
        }
        return sb.length() > 0 ? sb.toString().substring(1) : "";
    }

    private static String sortJsonArray(JSONArray array) {
        if (array.isEmpty()) {
            return null;
        }

        List list = new ArrayList();
        int size = array.size();
        for (int i = 0; i < size; i++) {
            Object value = array.get(i);
            if (value instanceof JSONObject) {
                list.add(sortJsonObject((JSONObject) value));
            } else if (value instanceof JSONArray) {
                list.add(sortJsonArray((JSONArray) value));
            } else {
                list.add(value);
            }
        }
        list.sort(Comparator.comparing(Object::toString));

        StringBuilder sb = new StringBuilder();
        for (Object object : list) {
            if (!(object instanceof String)) {
                throw new IllegalArgumentException("unsupported param type");
            }
            sb.append("&").append(object);
        }
        return sb.toString().substring(1);
    }
}
